<html>
  <head>
    <title>Blob Creation & Slicing</title>
    <script type="text/javascript" src="common.js"></script>
    <script type="text/javascript">
// We create < 3000 bytes of data, as that is the max for the browsertest.
var MAX_BYTES = 3000;

// Number of blobs constructed with raw data.
var NUM_RAW_BLOBS = 100;
// Number of blobs we create by slicing the raw data blobs.
var NUM_SLICES = 100;
// Number of blobs we create by sandwiching sliced blobs in between new data.
var NUM_SANDWICHES = 100;
var totalSize = 0;

var generatePsuedoRandomUint8Array = function(length) {
  var array = new Uint8Array(length);
  for (let i = 0; i < length; ++i) {
    array[i] = (17 + 23 * i) & 0xFF;
  }
  return array;
}

var test = function() {
  var blobs = [];

  // This should cause us to go straight to file.
  var savedToDiskDataSize = 190;
  var savedToDiskData = generatePsuedoRandomUint8Array(savedToDiskDataSize);

  // This should require multiple shared memory segments.
  var sharedMemoryDataSize = 15;
  var sharedMemoryData = generatePsuedoRandomUint8Array(sharedMemoryDataSize);
 
  var sandwichDataSize = 7;

  // This should fit in IPC.
  var ipcDataSize = 2;
  var ipcData = generatePsuedoRandomUint8Array(ipcDataSize);
  
  var expectedBlobData = [];
  for (let i = 0; i < NUM_RAW_BLOBS; ++i) {
    let data = [];
    if (i % 5 == 0) {
      data.push(sharedMemoryData);
    } else if (i % 13 == 0) {
      data.push(savedToDiskData);
    } else {
      data.push(ipcData);
    }
    expectedBlobData.push(data[data.length - 1]);
    let blob = new Blob(data, { content_type: "text/plain" });
    blobs.push(blob);
    totalSize += blob.size;
  }

  for (let i = 0; i < NUM_SLICES; ++i) {
    let origSize;
    let origData;
    let rawIndex = i % NUM_RAW_BLOBS;
    if (rawIndex % 5 == 0) {
      origSize = sharedMemoryDataSize;
      origData = sharedMemoryData;
    } else if (rawIndex % 13 == 0) {
      origSize = savedToDiskDataSize;
      origData = savedToDiskData;
     } else {
      origSize = ipcDataSize;
      origData = ipcData;
    }
    let blob;
    let expectedData;
    if (i % 2 == 0) {
      blob = blobs[i].slice(origSize / 2);
      expectedData = origData.slice(origSize / 2);
    } else {
      blob = blobs[i].slice(0, origSize / 2);
      expectedData = origData.slice(0, origSize / 2);
    }
    expectedBlobData.push(expectedData);
    blobs.push(blob);
  }
  
  var getBytes = function(string) {
    var bytes = [];
    for (let i = 0; i < string.length; ++i) {
      bytes.push(string.charCodeAt(i));
    }
    return bytes;
  }

  for (let i = 0; i < NUM_SANDWICHES; ++i) {
    let sliceIndex = NUM_RAW_BLOBS + (i % NUM_SLICES);
    let slicedDataSize = expectedBlobData[sliceIndex].length;
    blobs.push(new Blob(['pre', blobs[sliceIndex], 'post'], { content_type: "text/plain" }));
    totalSize += sandwichDataSize;

    let expectedData = new Uint8Array(sandwichDataSize + slicedDataSize);
    expectedData.set(getBytes("pre"), 0);
    expectedData.set(expectedBlobData[sliceIndex], 3);
    expectedData.set(getBytes("post"), 3 + slicedDataSize);
    expectedBlobData.push(expectedData);
  }
  shouldBeTrue("totalSize <= MAX_BYTES");

  var numRead = 0;
  for (let i = 0; i < blobs.length; i++) {
    (function(index, d) {
      var reader = new FileReader();
      reader.onloadend = function(e) {
        if (reader.error) {
          fail('Error when reading blob ' + index + ': ' + reader.error);
          return;
        }
        numRead++;
        debug('Finished reading blob ' + index);
        shouldBe('event.target.result.byteLength', d.length + '');
        shouldBe('new Uint8Array(event.target.result)',
                 '[' + d + ']');
        if (numRead >= blobs.length) {
          done('Done!');
        }
      }
      return reader;
    })(i, expectedBlobData[i]).readAsArrayBuffer(blobs[i]);
  }
};
    </script>
  </head>
  <body onLoad="test()">
    <div id="status">Starting...<br/></div>
  </body>
</html>
